package com.studykun.client.model.teacher;

import java.util.ArrayList;

import com.google.gwt.user.client.ui.InlineHTML;
import com.studykun.client.model.AbstractAgent;
import com.studykun.client.model.Agent;
import com.studykun.client.model.Card;
import com.studykun.client.model.Syllabus;
import com.studykun.client.model.Teacher;
import com.studykun.client.ui.HiraganaMatchedText;
import com.studykun.client.ui.InlinePanel;
import com.studykun.client.util.Action;
import com.studykun.client.util.AnswerHandler;
import com.studykun.client.util.CardSelector;
import com.studykun.client.util.EchoType;
import com.studykun.client.util.HasSyllabus;
import com.studykun.client.util.ProgressChangedHandler;
import com.studykun.client.util.ProgressChangedHandlers;
import com.studykun.client.util.Room;
import com.studykun.client.util.SimpleAvatar;
import com.studykun.client.util.Student;
import com.studykun.client.util.SyllabusChangedHandler;

public class HiraganaToKanjiTeacher extends AbstractAgent
    implements HasSyllabus, Teacher {
  final private ArrayList<SyllabusChangedHandler> syllabusChangedHandlers_ =
    new ArrayList<SyllabusChangedHandler>();
  final private ProgressChangedHandlers progressChangedHandlers_ =
    new ProgressChangedHandlers();
  private final HasSyllabus hasSyllabus_;
  private CardSelector cardSelector_;
  private HiraganaMatchedText hiraganaMatchedText_ = null;
  private Action cheatHandler_ = new Action() {
    public void doAction() {
      // Do nothing
    }
  };
  private AnswerHandler answerHandler_ = new AnswerHandler() {
    public void onAnswer(final String answer) {
      // Do nothing
    }
  };
  private SyllabusChangedHandler syllabusChangedHandler_ =
    new SyllabusChangedHandler() {
      public void onSyllabusChanged(final Syllabus syllabus) {
        cardSelector_ = new CardSelector(hasSyllabus_);
        progressChangedHandlers_.fireProgressChanged();
      }
    };
  
  public HiraganaToKanjiTeacher(
      final HasSyllabus hasSyllabus,
      final String teacherName) {
    super(new SimpleAvatar(teacherName, "teacher"));
    hasSyllabus_ = hasSyllabus;
    hasSyllabus_.addSyllabusChangedHandler(syllabusChangedHandler_);
  }
  
  public void onAdmit(
      final Agent agent,
      final Room room)
  {
    super.onAdmit(agent, room);
    if (agent == this) {
      this.sayIn(room, "今日は！！！");
      this.askQuestion(room);
    } else if (agent instanceof Teacher) {
      room.evict(this);
    }
  }
  
  public void askQuestion(
      final Room room)
  {
    if (cardSelector_ == null) {
      // Cannot ask a question without a working set.
      return;
    }
    
    final Card card = cardSelector_.getRandomCard();
    
    final InlinePanel inlinePanel = new InlinePanel();
    
    hiraganaMatchedText_ = new HiraganaMatchedText(card.hiragana(), card.kanji());
    inlinePanel.add(new InlineHTML("漢字で「"));
    inlinePanel.add(hiraganaMatchedText_);
    inlinePanel.add(new InlineHTML("」書いて下さい。"));
    this.sayIn(room, inlinePanel);
    answerHandler_ = new AnswerHandler() {
      public void onAnswer(final String answer) {
        if (answer.equals(card.kanjiClean())) {
          HiraganaToKanjiTeacher.this.sayIn(room, "いいですよ。");
          HiraganaToKanjiTeacher.this.askQuestion(room);
          card.adjustProgress(1);
        } else {
          HiraganaToKanjiTeacher.this.sayIn(room, "ちがう！");
          card.adjustProgress(-1);
        }
        progressChangedHandlers_.fireProgressChanged();
      }
    };
    cheatHandler_ = new Action() {
      public void doAction() {
        HiraganaToKanjiTeacher.this.sayIn(room, "Cheat: " + card.kanjiClean());
      }
    };
  }

  public Syllabus getSyllabus() {
    return hasSyllabus_.getSyllabus();
  }
  
  @Override
  public void onEcho(
      final EchoType echoType,
      final Room room,
      final Agent agent,
      final String message)
  {
    // Prevent infinite recursion caused by agent responding to itself.
    if (agent == this) {
      return;
    }
    
    if (agent instanceof Student) {
      switch (echoType) {
      case NORMAL:
        if (message.startsWith("/")) {
          if (message.equals("/cheat")) {
            cheatHandler_.doAction();
          }
          if (message.equals("/skip")) {
            this.askQuestion(room);
          }
          return;
        }
        
        answerHandler_.onAnswer(message);
        break;
      case PREVIEW:
        if (hiraganaMatchedText_ != null) {
          hiraganaMatchedText_.match(message);
        }
      }
    }
  }

  public void addSyllabusChangedHandler(
      final SyllabusChangedHandler handler) {
    syllabusChangedHandlers_.add(handler);
  }

  public void removeSyllabusChangedHandler(
      final SyllabusChangedHandler handler) {
    syllabusChangedHandlers_.remove(handler);
  }

  public void addProgressChangedHandler(
      final ProgressChangedHandler handler) {
    progressChangedHandlers_.addProgressChangedHandler(handler);
  }

  public void removeProgressChangedHandler(
      final ProgressChangedHandler handler) {
    progressChangedHandlers_.removeProgressChangedHandler(handler);
  }

  public String description() {
    return "Presents hiragana sentences for you to transliterate to kanji.";
  }
}
